Asssumes you have aready run: - config - workflow_deepseaNiN_Start

You now have the objects needed to explore the dataset and find the best way to apply biogeographic splits. This is a pre-step before running the workflow again on the split dataset to explore possible LKMs.

Finding Regional (biogeographic) Splits

This requires exploring the dataset to theorise the best ways to split the data with: - environmental biplots/colourings

then applying the splits.

Libraries

library(plotly)
library(readxl)

Exploring biplots

make full dataset to explore

should include all env Vars and otus to explore, and make species richness variable

#add species data and sp richness variable
env_sub_meta1<-cbind(env,otu_6)
env_sub_meta1$spRich<-rowSums(otu_6[,-c(1:which(colnames(otu_6)=="Zoanthidae"))]!=0)

#rename X
env_sub_meta1$X <- env$X.y
env_sub_meta1 <-env_sub_meta1 %>% select (-c(X.y))

#add samplID
env_sub_meta1$SampID<-envSel$SampID

Add provisional biotope data to env file

Note that biotopes were last assigned in march 2022 and therefore there are some addional samples that have not yet got a biotope assigned. These should just be NAs

biotopeInfo<-read_xlsx(file.path(dataPath, "inputs/MAREANO_provisional_biotope_classification_0322.xlsx"), sheet=1) %>%
  select(-c(x_coordinate_UTM33N, y_coordinate_UTM33N))

env_sub_meta<-left_join(env_sub_meta1,biotopeInfo)
Joining, by = "SampID"

a colour palette for discrete plots (see later in script)

cbPalette <- c("#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")

Find min max of vars for scales

colnames(env_sub_meta)
  [1] "X"                                     "bathy"                                
  [3] "diffME3"                               "diffME9"                              
  [5] "landscape"                             "msr1_mag"                             
  [7] "msr5_mag"                              "salt_max"                             
  [9] "salt_mean"                             "salt_min"                             
 [11] "salt_std"                              "slope3"                               
 [13] "slope9"                                "spd_max"                              
 [15] "spd_mean"                              "spd_min"                              
 [17] "spd_std"                               "temp_max"                             
 [19] "temp_mean"                             "temp_min"                             
 [21] "temp_std"                              "u_bott_mean"                          
 [23] "v_bott_mean"                           "X.y"                                  
 [25] "Y"                                     "MLDmax_Robinson"                      
 [27] "MLDmean_Robinson"                      "MLDmin_Robinson"                      
 [29] "MLDsd_Robinson"                        "Smax_Robinson"                        
 [31] "Smean_Robinson"                        "Smin_Robinson"                        
 [33] "Ssd_Robinson"                          "Tmax_Robinson"                        
 [35] "Tmean_Robinson"                        "Tmin_Robinson"                        
 [37] "Tsd_Robinson"                          "CDirmax_Robinson"                     
 [39] "CDirmean_Robinson"                     "CDirmin_Robinson"                     
 [41] "CDirsd_Robinson"                       "CSpdmax_Robinson"                     
 [43] "CSpdmean_Robinson"                     "CSpdmin_Robinson"                     
 [45] "CSpdsd_Robinson"                       "Umax_Robinson"                        
 [47] "Umean_Robinson"                        "Umin_Robinson"                        
 [49] "Usd_Robinson"                          "Vmax_Robinson"                        
 [51] "Vmean_Robinson"                        "Vmin_Robinson"                        
 [53] "Vsd_Robinson"                          "BO22_carbonphytoltmax_bdmean"         
 [55] "BO22_carbonphytoltmax_ss"              "BO22_carbonphytoltmin_bdmean"         
 [57] "BO22_carbonphytoltmin_ss"              "BO22_carbonphytomean_bdmean"          
 [59] "BO22_carbonphytomean_ss"               "BO22_carbonphytorange_bdmean"         
 [61] "BO22_carbonphytorange_ss"              "BO22_chloltmax_bdmean"                
 [63] "BO22_chloltmax_ss"                     "BO22_chloltmin_bdmean"                
 [65] "BO22_chloltmin_ss"                     "BO22_chlomean_bdmean"                 
 [67] "BO22_chlomean_ss"                      "BO22_chlorange_bdmean"                
 [69] "BO22_chlorange_ss"                     "BO22_dissoxltmax_bdmean"              
 [71] "BO22_dissoxltmin_bdmean"               "BO22_dissoxmean_bdmean"               
 [73] "BO22_dissoxrange_bdmean"               "BO22_icecoverltmax_ss"                
 [75] "BO22_icecoverltmin_ss"                 "BO22_icecovermean_ss"                 
 [77] "BO22_icecoverrange_ss"                 "BO22_icethickltmax_ss"                
 [79] "BO22_icethickltmin_ss"                 "BO22_icethickmean_ss"                 
 [81] "BO22_icethickrange_ss"                 "BO22_ironltmax_bdmean"                
 [83] "BO22_ironltmin_bdmean"                 "BO22_ironmean_bdmean"                 
 [85] "BO22_ironrange_bdmean"                 "BO22_nitrateltmax_bdmean"             
 [87] "BO22_nitrateltmin_bdmean"              "BO22_nitratemean_bdmean"              
 [89] "BO22_nitraterange_bdmean"              "BO22_phosphateltmax_bdmean"           
 [91] "BO22_phosphateltmin_bdmean"            "BO22_phosphatemean_bdmean"            
 [93] "BO22_phosphaterange_bdmean"            "BO22_ppltmax_bdmean"                  
 [95] "BO22_ppltmax_ss"                       "BO22_ppltmin_bdmean"                  
 [97] "BO22_ppltmin_ss"                       "BO22_ppmean_bdmean"                   
 [99] "BO22_ppmean_ss"                        "BO22_pprange_bdmean"                  
[101] "BO22_pprange_ss"                       "BO22_silicateltmax_bdmean"            
[103] "BO22_silicateltmin_bdmean"             "BO22_silicatemean_bdmean"             
[105] "BO22_silicaterange_bdmean"             "MS_biogeo05_dist_shore_5m"            
[107] "gmorph"                                "sedclass"                             
[109] "cobB"                                  "gravel"                               
[111] "mud"                                   "rock"                                 
[113] "sand"                                  "coords.x1"                            
[115] "coords.x2"                             "optional"                             
[117] "swDensRob_avs"                         "MLDmean_bathy"                        
[119] "MLDmin_bathy"                          "MLDmax_bathy"                         
[121] "Actiniaria.red"                        "Actiniaria.violet"                    
[123] "Actiniaria.white"                      "Actiniaria.yellow"                    
[125] "Actiniaria_buried.redish"              "Actiniaria_buried.yellow"             
[127] "Actiniaria_buried_dark"                "Actiniaria_epizoic"                   
[129] "Actiniaria_yellow_stolon"              "Actinostola_callosa"                  
[131] "Alcyonidium_sp."                       "Alcyonium_digitatum"                  
[133] "Amphicteis_ninonae"                    "Antedonoidea"                         
[135] "Antho_dichotoma"                       "Anthomastus_sp."                      
[137] "Anthothela_grandiflora"                "Aphroditidae"                         
[139] "Aporrhais_sp."                         "Arctica_islandica"                    
[141] "Asbestopluma_furcata"                  "Asbestopluma_pennatula"               
[143] "Ascidia_sp."                           "Ascidia_sp..transparent"              
[145] "Ascidia_sp._veined"                    "Ascidia_sp._violet"                   
[147] "Ascidia_virginea"                      "Ascidiacea_colonial_encrusting"       
[149] "Ascidiacea_colonial_encrusting.orange" "Ascidiacea_colonial_encrusting.white" 
[151] "Ascidiacea_colonial_erect"             "Ascidiacea_solitary"                  
[153] "Ascidiacea_solitary_big"               "Asconema_setubalense"                 
[155] "Astacidea"                             "Asterias_rubens"                      
[157] "Asteronyx_loveni"                      "Asterozoa"                            
[159] "Astropecten_irregularis"               "Astropectinidae"                      
[161] "Axinella_infundibuliformis"            "Axinellidae"                          
[163] "Bacterial_mat"                         "Balanus_balanus"                      
[165] "Balticina_sp."                         "Bathybiaster_vexillifer"              
[167] "Bathycrinus_carpenterii"               "Bathyplotes_natans"                   
[169] "Beringius_sp."                         "Bolocera_tuediae"                     
[171] "Bonelliidae"                           "Botryllus_sp."                        
[173] "Bourgueticrinina"                      "Brada_sp."                            
[175] "Bryozoa_calcareous_branched"           "Bryozoa_coral"                        
[177] "Bryozoa_encrusting"                    "Bryozoa_soft_branched"                
[179] "Bryozoa_soft_bush"                     "Buccinidae"                           
[181] "Buccinum_hydrophanum"                  "Buccinum_sp."                         
[183] "Buccinum_undatum"                      "Bugula_sp."                           
[185] "Cancer_pagurus"                        "Candelabrum_sp."                      
[187] "Caulophacus_arcticus"                  "Celleporidae"                         
[189] "Ceramaster.Hippasterias"               "Ceramaster_granularis"                
[191] "Cerianthidae"                          "Cerianthidae.cup_coral"               
[193] "Cerianthidae.dark"                     "Cerianthidae.violet"                  
[195] "Cerianthus_lloydii"                    "Cerianthus_vogti"                     
[197] "Chaetopterus_sp."                      "Chelonaplysilla_sp."                  
[199] "Chionoecetes_opilio"                   "Chlamys_sp."                          
[201] "Chondrocladia_gigantea"                "Cidaris_cidaris"                      
[203] "Ciona_intestinalis"                    "Cirripedia"                           
[205] "Cladorhiza_gelida"                     "Cladorhiza_sp."                       
[207] "Cladorhizidae"                         "Cladorhizidae_bottlebrush"            
[209] "Cladorhizidae_branched"                "Cladorhizidae_bush"                   
[211] "Cladorhizidae_stalked"                 "Clavularia_borealis"                  
[213] "Clavulariidae"                         "Colossendeis_angusta"                 
[215] "Colossendeis_proboscidea"              "Colossendeis_sp."                     
[217] "Colus_sp."                             "Conocrinus_lofotensis"                
[219] "Corella_parallelogramma"               "Corymorpha_glacialis"                 
[221] "Corymorpha_nutans"                     "Corymorpha_sand_stolon"               
[223] "Corymorpha_sp."                        "Crangonidae"                          
[225] "Craniella_cranium"                     "Craniella_sp."                        
[227] "Craniella_zetlandica"                  "Crisia_sp."                           
[229] "Crossaster_papposus"                   "Crossaster_sp."                       
[231] "Crossaster_squamatus"                  "Ctenodiscus_crispatus"                
[233] "Ctenophora_benthic"                    "Cucumaria_frondosa"                   
[235] "Cup_coral"                             "Dallina_septigera"                    
[237] "Dendrobeania_sp."                      "Dendrodoa_aggregata"                  
[239] "Dendronotus_sp."                       "Didemnidae"                           
[241] "Diplopteraster_multipes"               "Ditrupa_arietina"                     
[243] "Drifa_glomerata"                       "Duva_florida"                         
[245] "Dysidea_fragilis"                      "Echinoidea_irregular"                 
[247] "Echinoidea_regular"                    "Echinus_esculentus"                   
[249] "Echinus_sp."                           "Ectopleura_larynx"                    
[251] "Edwardsiidae"                          "Elpidia_glacialis"                    
[253] "Enteropneusta"                         "Eucratea_loricata"                    
[255] "Filograna_implexa"                     "Flustridae"                           
[257] "Flustrina"                             "Foraminifera_calcareous"              
[259] "Funiculina_quadrangularis"             "Geodia.Stelleta"                      
[261] "Geodia.Stryphnus"                      "Geodia_atlantica"                     
[263] "Geodia_barretti"                       "Geodia_macandrewii"                   
[265] "Geodia_phlegraei"                      "Geodia_sp."                           
[267] "Gersemia_rubiformis"                   "Geryon_trispinosus"                   
[269] "Gorgonacea"                            "Gorgonocephalus_sp."                  
[271] "Gracilechinus_acutus"                  "Gracilechinus_sp."                    
[273] "Grantia_compressa"                     "Halcampa_arctica"                     
[275] "Halcampa_sp."                          "Halcampoides_sp."                     
[277] "Halecium_sp."                          "Halichondria_sp."                     
[279] "Haliclona_sp."                         "Hamacantha_bowerbanki"                
[281] "Heliometra_glacialis"                  "Henricia_sp."                         
[283] "Henricia_sp..blue"                     "Henricia_sp..orange"                  
[285] "Henricia_sp..red"                      "Henricia_sp..violet"                  
[287] "Henricia_sp..white"                    "Henricia_sp..yellow"                  
[289] "Hexactinellida"                        "Hexactinellida_fan_shaped"            
[291] "Hexactinellida_parabol"                "Hexactinellida_urn.shaped"            
[293] "Hexadella_dedritifera"                 "Hippasteria_phrygiana"                
[295] "Hirudinea"                             "Hormathia_digitata"                   
[297] "Hormathia_nodosa"                      "Hormathia_sp."                        
[299] "Hormathiidae"                          "Horneridae"                           
[301] "Hyalonema_sp."                         "Hyas_coarctatus"                      
[303] "Hyas_sp."                              "Hydroides_norvegica"                  
[305] "Hydrozoa_feather"                      "Hydrozoa_solitary"                    
[307] "Hydrozoa_tree"                         "Hymedesmia_paupertas"                 
[309] "Hymenaster_pellucidus"                 "Hymenodiscus_coronata"                
[311] "Icasterias_panopla"                    "Isidella_lofotensis"                  
[313] "Isodictya_palmata"                     "Jasmineira_sp."                       
[315] "Kinetoskias_smitti"                    "Kolga_hyalina"                        
[317] "Kophobelemnon_stelliferum"             "Kukenthalia_borealis"                 
[319] "Lafoea_sp."                            "Laminaria_sp."                        
[321] "Laminariales"                          "Lanice_conchilega"                    
[323] "Latrunculia_sp."                       "Leieschara_sp."                       
[325] "Leptasterias_muelleri"                 "Leptasterias_sp."                     
[327] "Leptychaster_arcticus"                 "Lichenoporidae"                       
[329] "Liponema_multicorne"                   "Lithodes_maja"                        
[331] "Lithodidae"                            "Lophaster_furcifer"                   
[333] "Lophelia_pertusa"                      "Lucernaria_bathyphila"                
[335] "Luidia_ciliaris"                       "Luidia_sp."                           
[337] "Madrepora_oculata"                     "Mellonympha_mortenseni"               
[339] "Mesothuria_intestinalis"               "Molpadia_sp."                         
[341] "Molva_sp."                             "Munida_sarsi"                         
[343] "Munida_sp."                            "Munidopsis_serricornis"               
[345] "Muriceides_kuekenthali"                "Mycale_lingua"                        
[347] "Myxicola_sp."                          "Myxilla_incrustans"                   
[349] "Nemertea"                              "Nemertesia_antennina"                 
[351] "Neohela_sp."                           "Nephrops_norvegicus"                  
[353] "Nephtheidae"                           "Neptunea_despecta"                    
[355] "Neptunea_sp."                          "Nereididae"                           
[357] "Nothria_sp."                           "Oceanapia_robusta"                    
[359] "Ophiacanthidae"                        "Ophiocten_gracilis"                   
[361] "Ophiocten_sericeum"                    "Ophiocten_sp."                        
[363] "Ophiopholis_aculeata"                  "Ophiopleura_borealis"                 
[365] "Ophioscolex_glacialis"                 "Opisthobranchia"                      
[367] "Pachycerianthus_multiplicatus"         "Paguridae"                            
[369] "Paragorgia_arborea"                    "Paralithodes_camtschaticus"           
[371] "Paramuricea_placomus"                  "Parasmittina_jeffreysi"               
[373] "Parastichopus_tremulus"                "Patellogastropoda"                    
[375] "Pectinariidae"                         "Pectinidae"                           
[377] "Peltaster_placenta"                    "Pennatula_phosphorea"                 
[379] "Pennatulacea"                          "Phakellia.Axinella"                   
[381] "Phakellia_sp."                         "Phyllodoce_rosea"                     
[383] "Phyllodocidae"                         "Plicatellopsis_bowerbanki"            
[385] "Polycarpa_sp."                         "Polychaeta_fishingnet"                
[387] "Polychaeta_question_mark"              "Polychaeta_sediment_tube"             
[389] "Polychaeta_soft_thin_tube"             "Polychaeta_tube"                      
[391] "Polymastia_grimaldii"                  "Polymastia_sp."                       
[393] "Polymastiidae"                         "Polynoidae"                           
[395] "Pontaster_tenuispinus"                 "Porania.Poraniomorpha"                
[397] "Porania_sp."                           "Poraniidae"                           
[399] "Poraniomorpha_sp."                     "Poraniomorpha_tumida"                 
[401] "Porella_compressa"                     "Porella_sp."                          
[403] "Porifera_bat"                          "Porifera_big"                         
[405] "Porifera_branched"                     "Porifera_brown_papillae"              
[407] "Porifera_cupcake"                      "Porifera_dirty_yellow"                
[409] "Porifera_egg"                          "Porifera_encrusting"                  
[411] "Porifera_encrusting.bluegrey"          "Porifera_encrusting.brown"            
[413] "Porifera_encrusting.green"             "Porifera_encrusting.grey"             
[415] "Porifera_encrusting.orange"            "Porifera_encrusting.purple"           
[417] "Porifera_encrusting.red"               "Porifera_encrusting.white"            
[419] "Porifera_encrusting.yellow"            "Porifera_erect"                       
[421] "Porifera_fan"                          "Porifera_fan.big"                     
[423] "Porifera_fan.small"                    "Porifera_fan.white"                   
[425] "Porifera_lily"                         "Porifera_lollipop"                    
[427] "Porifera_medium.white"                 "Porifera_medium.yellow"               
[429] "Porifera_medium_round"                 "Porifera_parabol"                     
[431] "Porifera_small.green"                  "Porifera_small.irregular"             
[433] "Porifera_small.orange"                 "Porifera_small.round_yellow"          
[435] "Porifera_small.spikey"                 "Porifera_small.stalked"               
[437] "Porifera_small.yellow"                 "Porifera_string"                      
[439] "Porifera_urn"                          "Porifera_white_bush"                  
[441] "Porifera_window"                       "Pourtalesia_jeffreysi"                
[443] "Primnoa_resedaeformis"                 "Protanthea_simplex"                   
[445] "Pseudamussium_peslutrae"               "Pseudarchaster_parelii"               
[447] "Psolus_phantapus"                      "Psolus_sp."                           
[449] "Psolus_squamatus"                      "Pteraster_militaris"                  
[451] "Pteraster_obscurus"                    "Pteraster_pulvillus"                  
[453] "Pteraster_sp."                         "Ptychogastria_polaris"                
[455] "Quasillina_brevis"                     "Quasillina_sp."                       
[457] "Radicipes_sp."                         "Reteporella_beaniana"                 
[459] "Reteporella_sp."                       "Sabellidae"                           
[461] "Saduria_sp."                           "Scaphopoda"                           
[463] "Sclerocrangon_ferox"                   "Serpulidae"                           
[465] "Sertulariidae"                         "Siboglinidae"                         
[467] "Smittinidae"                           "Solaster_endeca"                      
[469] "Solaster_sp."                          "Solasteridae"                         
[471] "Spatangoida"                           "Spatangus_purpureus"                  
[473] "Spiochaetopterus_tubes"                "Spionidae"                            
[475] "Spirobranchus_triqueter"               "Spirontocaris_sp."                    
[477] "Stauromedusae"                         "Steletta_grubei"                      
[479] "Stelletta_sp."                         "Stichastrella_rosea"                  
[481] "Strongylocentrotus_sp."                "Stryphnus_ponderosus"                 
[483] "Styela_sp."                            "Stylasteridae"                        
[485] "Stylocordyla_borealis"                 "Swiftia_sp."                          
[487] "Sycon_sp."                             "Sycon_stalked"                        
[489] "Tentorium_semisuberites"               "Terebellida"                          
[491] "Tetilla_sp."                           "Thenea_abyssorum"                     
[493] "Thenea_levis"                          "Thenea_sp."                           
[495] "Thuiaria_obsoleta"                     "Thuiaria_thuja"                       
[497] "Tremaster_mirabilis"                   "Tubularia_indivisa"                   
[499] "Tubularia_sp."                         "Tubulariidae"                         
[501] "Tunicata_trunk"                        "Umbellula_encrinus"                   
[503] "Urasterias_lincki"                     "Urticina_sp."                         
[505] "Virgularia_mirabilis"                  "Weberella_bursa"                      
[507] "Zoanthidae"                            "gnmds1"                               
[509] "gnmds2"                                "dca1"                                 
[511] "dca2"                                 

Plots with CONTINUOUS colour scales (variables)

Bathy v Temp w gnmds ax 1
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Tmean_Robinson,
                          y = bathy)) +
  theme_classic() +
  geom_point(aes(colour = gnmds1),
             size = 1) +
  scale_colour_gradientn(limits = c(min(env_sub_meta$gnmds1),
                                    max(env_sub_meta$gnmds1)),
                        colors=c('red','yellow','green'))+
  ggtitle("Temp (mean Robinson) vs Bathy - coloured by gnmds r6 ax1")

tb_ax1

Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mbathy_v_temp_nmds1.png"),
       device = "png",
       dpi=300 )
Saving 7 x 7 in image
Bathy v Density w gnmds ax 1
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = swDensRob_avs,
                          y = bathy)) +
  theme_classic() +
  geom_point(aes(colour = gnmds1),
             size = 1) +
  scale_colour_gradientn(limits = c(min(env_sub_meta$gnmds1),
                                    max(env_sub_meta$gnmds1)),
                        colors=c('red','yellow','green'))+
  ggtitle("Density vs Bathy - coloured by gnmds1")

tb_ax1

Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_bathy_v_dens_gnmds1.png"),
       device = "png",
       dpi=300 )
Saving 7 x 7 in image
Bathy v Temp w longitude
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Tmean_Robinson,
                          y = bathy)) +
  theme_classic() +
  geom_point(aes(colour = X.y),
             size = 1) +
  scale_colour_gradientn(limits = c(-107939, 1162261),
                        colors=c('red','yellow','blue'))+
  ggtitle("Temp (mean Robinson) vs Bathy - coloured by longitude")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mbathy_v_temp_longitude.png"),
       device = "png",
       dpi=300 )
Bathy v Temp w latitude
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Tmean_Robinson,
                          y = bathy)) +
  theme_classic() +
  geom_point(aes(colour = Y),
             size = 1) +
  scale_colour_gradientn(limits = c(6944134, 8949734),
                        colors=c('red','yellow','blue'))+
  ggtitle("Temp (mean Robinson) vs Bathy - coloured by latitude")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mbathy_v_temp_latitude.png"),
       device = "png",
       dpi=300 )
Bathy v Temp w iceCovLTMax
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Tmean_Robinson,
                          y = bathy)) +
  theme_classic() +
  geom_point(aes(colour = BO22_icecoverltmax_ss),
             size = 1) +
  scale_colour_gradientn(limits = c(0,0.93),
                        colors=c('grey','turquoise','blue'))+
  ggtitle("Temp (mean Robinson) vs Bathy - coloured by ice cover LT max")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mbathy_v_temp_iceCovLTmax.png"),
       device = "png",
       dpi=300 )
Bathy v Salinity coloured by temp
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Smax_Robinson,
                          y = bathy)) +
  theme_classic() +
  geom_point(aes(colour = Tmean_Robinson),
             size = 1) +
  scale_colour_gradientn(limits = c(-1.1, 8.5),
                        colors=c('red','yellow','green'))+
  ggtitle("Salinity (max Robinson) vs Bathy - coloured by av Temp (R)")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mbathy_v_salMax_temp.png"),
       device = "png",
       dpi=300 )
Salinity v Temp gnmds1
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Smax_Robinson,
                          y = Tmean_Robinson)) +
  theme_classic() +
  geom_point(aes(colour = gnmds1),
             size = 1) +
scale_colour_gradientn(limits = c(min(env_sub_meta$gnmds1),
                                    max(env_sub_meta$gnmds1)),
                        colors=c('red','yellow','green'))+
  ggtitle("Temp (mean Robinson) vs Salinity (max R) - coloured by gnmds r6 ax 1 - grey 2.5-5")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mtempRmean_v_salinityRmax_nmds1.png"),
       device = "png",
       dpi=300 )
Salinity v Temp dissoxmean
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Smax_Robinson,
                          y = Tmean_Robinson)) +
  theme_classic() +
  geom_point(aes(colour = BO22_dissoxmean_bdmean),
             size = 1) +
scale_colour_gradientn(limits = c(282.5, 372.2),
                        colors=c('red','yellow','green'))+
  ggtitle("Temp (mean Robinson) vs Salinity (max R) - coloured by dissolved oxygen")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mtempRmean_v_salinityRmax_disooxmean.png"),
       device = "png",
       dpi=300 )
TS - icecoverLTMax
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Smax_Robinson,
                          y = Tmean_Robinson)) +
  theme_classic() +
  geom_point(aes(colour = BO22_icecoverltmax_ss),
             size = 1) +
  scale_colour_gradientn(limits = c(0,0.93),
                        colors=c('blue','green','red'))+
  ggtitle("Temp (AvR) v Salinity (maxR) - coloured by ice cover LT max")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mtempRmean_v_salinityRmax_iceCoveLTmax.png"),
       device = "png",
       dpi=800 )
X v Y - gnmds1
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = X,
                          y = Y)) +
  theme_classic() +
  geom_point(aes(colour = gnmds1),
             size = 1) +
  scale_colour_gradientn(limits = c(min(env_sub_meta$gnmds1),
                                    max(env_sub_meta$gnmds1)),
                        colors=c('red','yellow','green'))+
  ggtitle("Geography (X v Y) - coloured by gnmds1")

ggplotly(tb_ax1)

NA
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_X_v_Y_gnmds1.png"),
       device = "png",
       dpi=300 )
Saving 7 x 7 in image
X v Y - density
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = X.y,
                          y = Y)) +
  theme_classic() +
  geom_point(aes(colour = swDensRob_avs),
             size = 1) +
  scale_colour_gradientn(limits = c(min(env_sub_meta$swDensRob_avs), 
                                    max(env_sub_meta$swDensRob_avs)),
                        colors=c('blue','green','red'))+
  ggtitle("Geography (X v Y) - coloured by water density")

tb_ax1

Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_X_v_Y_swDenRobavs.png"),
       device = "png",
       dpi=800 )
Saving 7 x 7 in image
X v Y - dissox
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = X.y,
                          y = Y)) +
  theme_classic() +
  geom_point(aes(colour = BO22_dissoxmean_bdmean),
             size = 1) +
  scale_colour_gradientn(limits = c(282,373),
                        colors=c('blue','green','red'))+
  ggtitle("Geography (X v Y) - coloured by dissovled oxygen")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_X_v_Y_dissox.png"),
       device = "png",
       dpi=800 )
X v Y - icecoverLTMax
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = X.y,
                          y = Y)) +
  theme_classic() +
  geom_point(aes(colour = BO22_icecoverltmax_ss),
             size = 1) +
  scale_colour_gradientn(limits = c(0.00001,0.93),
                        colors=c('blue','green','red'))+
  ggtitle("Geography (X v Y) - coloured by ice cover LT max - grey <0.00001")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_X_v_Y_iceCoveLTmax.png"),
       device = "png",
       dpi=800 )
Temp v disoxltmin gnmds
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Tmean_Robinson,
                          y = BO22_dissoxmean_bdmean)) +
  theme_classic() +
  geom_point(aes(colour = gnmds1),
             size = 1) +
  scale_colour_gradientn(limits = c(-2.3, 2),
                        colors=c('red','yellow','green'))+
  ggtitle("Temp (mean Robinson) v disox mean - coloured by gnmds ax 1")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_TmeanR_v_dissoxltmin_gnmds1.png"),
       device = "png",
       dpi=300 )
Temp v disoxltmin bathy
tb_ax1<- ggplot(data = env_sub_meta,
                      aes(x = Tmean_Robinson,
                          y = BO22_dissoxmean_bdmean)) +
  theme_classic() +
  geom_point(aes(colour = bathy),
             size = 1) +
  scale_colour_gradientn(limits = c(-702, -38),
                        colors=c('red','yellow','green'))+
  ggtitle("Temp (mean Robinson) v disox mean - coloured by bathymetry")

tb_ax1
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500mTmeanR_v_dissoxltmin_bathy.png"),
       device = "png",
       dpi=300 )

Plots with DISCRETE colour scales (variables)

X v Y with mld-bathy categories

dis_split <- ggplot(data = env,
              aes(x = X.y,
                  y = Y)) +
  theme_classic() +
  geom_point(aes(colour = MLDmean_bathy),
             size = 1) +
  scale_colour_manual(values=cbPalette)+
 # scale_colour_brewer(palette = "Set3") +
  ggtitle("Easting vs Northing - coloured by Mixed layer depth proximity")

dis_split
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_XvY_MLDmeanBathy.png"),
       device = "png",
       dpi=300 )

categorise gnmds

env_sub_meta$ax1cat<-cut(env_sub_meta$gnmds1, 
      breaks=c(-3.2,-3,-2,-1,0,1,2,3,3.46))

env_sub_meta$ax2cat<-cut(env_sub_meta$gnmds2, 
      breaks=c(-1.9,-1,0,1,2,3,4,4.9))

X v Y with gnmds ax 1 as HC categories

dis_split <- ggplot(data = env_sub_meta,
              aes(x = X.y,
                  y = Y)) +
  theme_classic() +
  geom_point(aes(colour = ax1cat),
             size = 1) +
 # scale_colour_manual(values=cbPalette) +# non-ordered colourblind pallette
  scale_colour_brewer(palette = "Spectral") + # ordered colourblind pallette
  ggtitle("Easting vs Northing - coloured by gnmds axis 1 HC units")

dis_split
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_XvY_ax1cat.png"),
       device = "png",
       dpi=300 )

categorise temp 5.1

env_sub_meta$temp5_1<-cut(env_sub_meta$Tmean_Robinson, 
      breaks=c(-1.1, 5.1, 8.5))
#

X v Y with temp 5.1

dis_split <- ggplot(data = env_sub_meta,
              aes(x = X.y,
                  y = Y)) +
  theme_classic() +
  geom_point(aes(colour = temp5_1),
             size = 1) +
 # scale_colour_manual(values=cbPalette) +# non-ordered colourblind pallette
  scale_colour_brewer(palette = "Set1") + # ordered colourblind pallette
  ggtitle("Easting vs Northing - coloured by temp thresholded at 5.1*C")

dis_split
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_XvY_temp5_1.png"),
       device = "png",
       dpi=300 )

categorise dissox

env_sub_meta$dissoxav305<-cut(env_sub_meta$BO22_dissoxmean_bdmean, 
     # breaks=c(256, 282, 360)) #ltmin
     breaks=c(282.5,305,372.2),
     labels=c("lowO2","hiO2")) #mean
#

X v Y with dissox

dis_split <- ggplot(data = env_sub_meta,
              aes(x = X.y,
                  y = Y)) +
  theme_classic() +
  geom_point(aes(colour = dissoxav305),
             size = 1) +
 # scale_colour_manual(values=cbPalette) +# non-ordered colourblind pallette
  scale_colour_brewer(palette = "Set1") + # ordered colourblind pallette
  ggtitle("Easting vs Northing - coloured by dissox av thresholded at 305")

dis_split
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_XvY_dissoxav305.png"),
       device = "png",
       dpi=300 )

categorise iceCovLTMax

env_sub_meta$iceMx_gt0<-cut(env_sub_meta$BO22_icecoverltmax_ss, 
      breaks=c(0, 0.00001, 0.92838))
#

X v Y with temp 5.1

dis_split <- ggplot(data = env_sub_meta,
              aes(x = X.y,
                  y = Y)) +
  theme_classic() +
  geom_point(aes(colour = iceMx_gt0),
             size = 1) +
 # scale_colour_manual(values=cbPalette) +# non-ordered colourblind pallette
  scale_colour_brewer(palette = "Set1") + # ordered colourblind pallette
  ggtitle("Easting vs Northing - coloured by ice LT Max thresholded at >0")

dis_split
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_XvY_iceLTmx_gt0.png"),
       device = "png",
       dpi=300 )

X v Y with gnmds ax 2 as HC categories

dis_split <- ggplot(data = env_sub_meta,
              aes(x = X.y,
                  y = Y)) +
  theme_classic() +
  geom_point(aes(colour = ax2cat),
             size = 1) +
 # scale_colour_manual(values=cbPalette) +# non-ordered colourblind pallette
  scale_colour_brewer(palette = "Spectral") + # ordered colourblind pallette
  ggtitle("Easting vs Northing - coloured by gnmds axis 2 HC units")

dis_split
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_XvY_ax2cat.png"),
       device = "png",
       dpi=300 )

Gnmds w temp 5.1


t_gmo <- ggplot(data = env_sub_meta,
                     aes(x = gnmds1,
                         y = gnmds2)) +
  theme_classic() +
  coord_fixed() +
  ggtitle("GNMDS coloured by temp 5.1 threshold",
          subtitle = "First run") +
  geom_point(aes(colour = factor(temp5_5))) +
  geom_vline(xintercept = 0,
             linetype = 2,
             colour = "lightgray") +
  geom_hline(yintercept = 0,
             linetype = 2,
             colour = "lightgray")+
  guides(colour=guide_legend(ncol=2))

t_gmo
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_temp5_1.png"),
       device = "png",
       dpi=300 )

Gnmds w dissox 305


o_gmo <- ggplot(data = env_sub_meta,
                     aes(x = gnmds1,
                         y = gnmds2)) +
  theme_classic() +
  coord_fixed() +
  ggtitle("GNMDS coloured by dissox 305 threshold",
          subtitle = "First run") +
  geom_point(aes(colour = factor(dissox305))) +
  geom_vline(xintercept = 0,
             linetype = 2,
             colour = "lightgray") +
  geom_hline(yintercept = 0,
             linetype = 2,
             colour = "lightgray")+
  guides(colour=guide_legend(ncol=2))

o_gmo
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_dissox305.png"),
       device = "png",
       dpi=300 )

Gnmds w iceLT max >0


i_gmo <- ggplot(data = env_sub_meta,
                     aes(x = gnmds1,
                         y = gnmds2)) +
  theme_classic() +
  coord_fixed() +
  ggtitle("GNMDS coloured by ice max >0 threshold",
          subtitle = "First run") +
  geom_point(aes(colour = factor(iceMx_gt0))) +
  geom_vline(xintercept = 0,
             linetype = 2,
             colour = "lightgray") +
  geom_hline(yintercept = 0,
             linetype = 2,
             colour = "lightgray")+
  guides(colour=guide_legend(ncol=2))

i_gmo
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_iceMxgt0.png"),
       device = "png",
       dpi=300 )
comp<-i_gmo+o_gmo+t_gmo
Save the plot


##### Save some outputs

ggexport(comp,
          filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_compare.png"),
          width = 1500,
          height = 500)

X v Y with landscape

dis_split <- ggplot(data = env_sub_meta,
              aes(x = X.y,
                  y = Y)) +
  theme_classic() +
  geom_point(aes(colour = as.factor(landscape)),
             size = 1) +
 # scale_colour_manual(values=cbPalette) +# non-ordered colourblind pallette
  scale_colour_brewer(palette = "Set1") + # ordered colourblind pallette
  ggtitle("Easting vs Northing - coloured by landscape")

dis_split

Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_XvY_landscape.png"),
       device = "png",
       dpi=300 )
Saving 7 x 7 in image

GNMDS PLOTS

colour palette to cope with up to 25 categorical colours
c25 <- c(
  "dodgerblue2", "#E31A1C", # red
  "green4",
  "#6A3D9A", # purple
  "#FF7F00", # orange
  "black", "gold1",
  "skyblue2", "#FB9A99", # lt pink
  "palegreen2",
  "#CAB2D6", # lt purple
  "#FDBF6F", # lt orange
  "gray70", "khaki2",
  "maroon", "orchid1", "hiDens_b1500pink1", "blue1", "steelblue4",
  "darkturquoise", "green1", "yellow4", "yellow3",
  "darkorange4", "brown"
)

gnmds with density categories

summary(env_sub_meta$swDensRob_avs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1035    1036    1037    1037    1038    1041 
env_sub_meta$densCat<-cut(env_sub_meta$swDensRob_avs, 
      breaks=c(1035,1036,1037,1038,1039,1040,1041))

p_dens <- ggplot(data = env_sub_meta,
                     aes(x = gnmds1,
                         y = gnmds2)) +
  theme_classic() +
  coord_fixed() +
  ggtitle("GNMDS coloured by density bins") +
  geom_point(aes(colour = factor(densCat))) +
   scale_colour_manual(values=c25)+
  geom_vline(xintercept = 0,
             linetype = 2,
             colour = "lightgray") +
  geom_hline(yintercept = 0,
             linetype = 2,
             colour = "lightgray")+
  guides(colour=guide_legend(ncol=2))

ggplotly(p_dens)

NA
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_densityCat.png"),
       device = "png",
       dpi=300 )
Saving 7 x 7 in image

gnmds with density 1036 threshold

summary(env_sub_meta$swDensRob_avs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1035    1036    1037    1037    1038    1041 
env_sub_meta$densCat1036<-cut(env_sub_meta$swDensRob_avs, 
      breaks=c(1035,1036,1041))

p_dens <- ggplot(data = env_sub_meta,
                     aes(x = gnmds1,
                         y = gnmds2)) +
  theme_classic() +
  coord_fixed() +
  ggtitle("GNMDS coloured by density threshold 1036") +
  geom_point(aes(colour = factor(densCat1036))) +
   scale_colour_manual(values=c25)+
  geom_vline(xintercept = 0,
             linetype = 2,
             colour = "lightgray") +
  geom_hline(yintercept = 0,
             linetype = 2,
             colour = "lightgray")+
  guides(colour=guide_legend(ncol=2))

ggplotly(p_dens)

NA
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_densityCat1036.png"),
       device = "png",
       dpi=300 )
Saving 7 x 7 in image

gnmds with bathy categories

summary(env_sub_meta$bathy)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  -2717   -2145   -1954   -1955   -1652   -1504 
env_sub_meta$bathyCat<-cut(env_sub_meta$bathy, 
      breaks=c(-2717,-2600,-2500,-2400,-2300,-2200,-2100,-2000,-1900,-1800,-1700,-1600,-1504),
      labels=c("> 2600m","2500-2600m","2400-2500m","2300-2400m","2200-2300m","2100-2200m",
               "2000-2100m","1900-2000m","1800-1900m","1700-1800m",
               "1600-1700m","< 1600m"))

p_bath <- ggplot(data = env_sub_meta,
                     aes(x = gnmds1,
                         y = gnmds2)) +
  theme_classic() +
  coord_fixed() +
  ggtitle("GNMDS coloured by sediment class") +
  geom_point(aes(colour = bathyCat)) +
  scale_fill_binned()+
  geom_vline(xintercept = 0,
             linetype = 2,
             colour = "lightgray") +
  geom_hline(yintercept = 0,
             linetype = 2,
             colour = "lightgray")+
  guides(colour=guide_legend(ncol=2))

ggplotly(p_bath)

NA
NA
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_bahtyCat.png"),
       device = "png",
       dpi=300 )
Saving 7 x 7 in image

gnmds with taxa


p_bath <- ggplot(data = env_sub_meta,
                     aes(x = gnmds1,
                         y = gnmds2)) +
  theme_classic() +
  coord_fixed() +
  ggtitle("GNMDS coloured by sediment class") +
  geom_point(aes(colour = as.factor(Umbellula_encrinus))) +
  scale_fill_binned(type = "viridis")+
  geom_vline(xintercept = 0,
             linetype = 2,
             colour = "lightgray") +
  geom_hline(yintercept = 0,
             linetype = 2,
             colour = "lightgray")+
  guides(colour=guide_legend(ncol=2))

ggplotly(p_bath)

NA
NA
Save the plot
ggsave(filename = file.path(dataPath,"outputs/HiDensBelow1500m_gnmds_bahtyCat.png"),
       device = "png",
       dpi=300 )

Save environment

EDIT AREA FIRST!

save.image("I:/Scripts/deepseaNiN/Renv_deepseaNiN_HiDensBelow1500m.RData") # edit area first

NOW CLEAR ENVIRONMENT BEFORE RUNNING FOR NEW AREA

LS0tDQp0aXRsZTogIk1BUkVBTk8gLSBOaU46c3BsaXR0aW5nIGJpb2dlb2dyYXBoaWMgcmVnaW9uc19IaURlbnNCZWxvdzE1MDBtIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KQXNzc3VtZXMgeW91IGhhdmUgYXJlYWR5IHJ1bjoNCi0gY29uZmlnDQotIHdvcmtmbG93X2RlZXBzZWFOaU5fU3RhcnQNCg0KWW91IG5vdyBoYXZlIHRoZSBvYmplY3RzIG5lZWRlZCB0byBleHBsb3JlIHRoZSBkYXRhc2V0IGFuZCBmaW5kIHRoZSBiZXN0IHdheSB0byBhcHBseSBiaW9nZW9ncmFwaGljIHNwbGl0cy4gVGhpcyBpcyBhIHByZS1zdGVwIGJlZm9yZSBydW5uaW5nIHRoZSB3b3JrZmxvdyBhZ2FpbiBvbiB0aGUgc3BsaXQgZGF0YXNldCB0byBleHBsb3JlIHBvc3NpYmxlIExLTXMuDQoNCiMgRmluZGluZyBSZWdpb25hbCAoYmlvZ2VvZ3JhcGhpYykgU3BsaXRzDQoNClRoaXMgcmVxdWlyZXMgZXhwbG9yaW5nIHRoZSBkYXRhc2V0IHRvIHRoZW9yaXNlIHRoZSBiZXN0IHdheXMgdG8gc3BsaXQgdGhlIGRhdGEgd2l0aDoNCi0gZW52aXJvbm1lbnRhbCBiaXBsb3RzL2NvbG91cmluZ3MNCg0KDQp0aGVuIGFwcGx5aW5nIHRoZSBzcGxpdHMuIA0KDQojIyMgTGlicmFyaWVzDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShyZWFkeGwpDQpgYGANCg0KDQoNCg0KIyMgRXhwbG9yaW5nIGJpcGxvdHMNCiMjIyMgbWFrZSBmdWxsIGRhdGFzZXQgdG8gZXhwbG9yZSANCnNob3VsZCBpbmNsdWRlIGFsbCBlbnYgVmFycyBhbmQgb3R1cyB0byBleHBsb3JlLCBhbmQgbWFrZSBzcGVjaWVzIHJpY2huZXNzIHZhcmlhYmxlDQoNCmBgYHtyfQ0KI2FkZCBzcGVjaWVzIGRhdGEgYW5kIHNwIHJpY2huZXNzIHZhcmlhYmxlDQplbnZfc3ViX21ldGExPC1jYmluZChlbnYsb3R1XzYpDQplbnZfc3ViX21ldGExJHNwUmljaDwtcm93U3VtcyhvdHVfNlssLWMoMTp3aGljaChjb2xuYW1lcyhvdHVfNik9PSJab2FudGhpZGFlIikpXSE9MCkNCg0KI3JlbmFtZSBYDQplbnZfc3ViX21ldGExJFggPC0gZW52JFgueQ0KZW52X3N1Yl9tZXRhMSA8LWVudl9zdWJfbWV0YTEgJT4lIHNlbGVjdCAoLWMoWC55KSkNCg0KI2FkZCBzYW1wbElEDQplbnZfc3ViX21ldGExJFNhbXBJRDwtZW52U2VsJFNhbXBJRA0KDQpgYGANCg0KDQojIyMgQWRkIHByb3Zpc2lvbmFsIGJpb3RvcGUgZGF0YSB0byBlbnYgZmlsZQ0KTm90ZSB0aGF0IGJpb3RvcGVzIHdlcmUgbGFzdCBhc3NpZ25lZCBpbiBtYXJjaCAyMDIyIGFuZCB0aGVyZWZvcmUgdGhlcmUgYXJlIHNvbWUgYWRkaW9uYWwgc2FtcGxlcyB0aGF0IGhhdmUgbm90IHlldCBnb3QgYSBiaW90b3BlIGFzc2lnbmVkLiBUaGVzZSBzaG91bGQganVzdCBiZSBOQXMNCmBgYHtyfQ0KYmlvdG9wZUluZm88LXJlYWRfeGxzeChmaWxlLnBhdGgoZGF0YVBhdGgsICJpbnB1dHMvTUFSRUFOT19wcm92aXNpb25hbF9iaW90b3BlX2NsYXNzaWZpY2F0aW9uXzAzMjIueGxzeCIpLCBzaGVldD0xKSAlPiUNCiAgc2VsZWN0KC1jKHhfY29vcmRpbmF0ZV9VVE0zM04sIHlfY29vcmRpbmF0ZV9VVE0zM04pKQ0KDQplbnZfc3ViX21ldGE8LWxlZnRfam9pbihlbnZfc3ViX21ldGExLGJpb3RvcGVJbmZvKQ0KYGBgDQoNCg0KDQoNCg0KIyMjIGEgY29sb3VyIHBhbGV0dGUgZm9yIGRpc2NyZXRlIHBsb3RzIChzZWUgbGF0ZXIgaW4gc2NyaXB0KQ0KDQpgYGB7cn0NCmNiUGFsZXR0ZSA8LSBjKCIjOTk5OTk5IiwgIiNFNjlGMDAiLCAiIzU2QjRFOSIsICIjMDA5RTczIiwgIiNGMEU0NDIiLCAiIzAwNzJCMiIsICIjRDU1RTAwIiwgIiNDQzc5QTciKQ0KYGBgDQoNCiMjIyBGaW5kIG1pbiBtYXggb2YgdmFycyBmb3Igc2NhbGVzDQpgYGB7cn0NCmNvbG5hbWVzKGVudl9zdWJfbWV0YSkNCmBgYA0KDQoNCg0KIyMjIFBsb3RzIHdpdGggQ09OVElOVU9VUyBjb2xvdXIgc2NhbGVzICh2YXJpYWJsZXMpDQoNCg0KIyMjIyMgQmF0aHkgdiBUZW1wIHcgZ25tZHMgYXggMQ0KYGBge3J9DQp0Yl9heDE8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IFRtZWFuX1JvYmluc29uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gYmF0aHkpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGdubWRzMSksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50bihsaW1pdHMgPSBjKG1pbihlbnZfc3ViX21ldGEkZ25tZHMxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChlbnZfc3ViX21ldGEkZ25tZHMxKSksDQogICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnM9YygncmVkJywneWVsbG93JywnZ3JlZW4nKSkrDQogIGdndGl0bGUoIlRlbXAgKG1lYW4gUm9iaW5zb24pIHZzIEJhdGh5IC0gY29sb3VyZWQgYnkgZ25tZHMgcjYgYXgxIikNCg0KdGJfYXgxDQoNCmBgYA0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbWJhdGh5X3ZfdGVtcF9ubWRzMS5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCmBgYA0KIyMjIyMgQmF0aHkgdiBEZW5zaXR5IHcgZ25tZHMgYXggMQ0KYGBge3J9DQp0Yl9heDE8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IHN3RGVuc1JvYl9hdnMsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBiYXRoeSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZ25tZHMxKSwNCiAgICAgICAgICAgICBzaXplID0gMSkgKw0KICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGxpbWl0cyA9IGMobWluKGVudl9zdWJfbWV0YSRnbm1kczEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KGVudl9zdWJfbWV0YSRnbm1kczEpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycz1jKCdyZWQnLCd5ZWxsb3cnLCdncmVlbicpKSsNCiAgZ2d0aXRsZSgiRGVuc2l0eSB2cyBCYXRoeSAtIGNvbG91cmVkIGJ5IGdubWRzMSIpDQoNCnRiX2F4MQ0KDQpgYGANCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG1fYmF0aHlfdl9kZW5zX2dubWRzMS5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCmBgYA0KDQoNCg0KDQoNCiMjIyMjIEJhdGh5IHYgVGVtcCB3IGxvbmdpdHVkZQ0KYGBge3J9DQp0Yl9heDE8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IFRtZWFuX1JvYmluc29uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gYmF0aHkpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IFgueSksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50bihsaW1pdHMgPSBjKC0xMDc5MzksIDExNjIyNjEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzPWMoJ3JlZCcsJ3llbGxvdycsJ2JsdWUnKSkrDQogIGdndGl0bGUoIlRlbXAgKG1lYW4gUm9iaW5zb24pIHZzIEJhdGh5IC0gY29sb3VyZWQgYnkgbG9uZ2l0dWRlIikNCg0KdGJfYXgxDQoNCmBgYA0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbWJhdGh5X3ZfdGVtcF9sb25naXR1ZGUucG5nIiksDQogICAgICAgZGV2aWNlID0gInBuZyIsDQogICAgICAgZHBpPTMwMCApDQpgYGANCiMjIyMjIEJhdGh5IHYgVGVtcCB3IGxhdGl0dWRlDQpgYGB7cn0NCnRiX2F4MTwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gVG1lYW5fUm9iaW5zb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBiYXRoeSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gWSksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50bihsaW1pdHMgPSBjKDY5NDQxMzQsIDg5NDk3MzQpLA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzPWMoJ3JlZCcsJ3llbGxvdycsJ2JsdWUnKSkrDQogIGdndGl0bGUoIlRlbXAgKG1lYW4gUm9iaW5zb24pIHZzIEJhdGh5IC0gY29sb3VyZWQgYnkgbGF0aXR1ZGUiKQ0KDQp0Yl9heDENCg0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtYmF0aHlfdl90ZW1wX2xhdGl0dWRlLnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KYGBgDQojIyMjIyBCYXRoeSB2IFRlbXAgdyBpY2VDb3ZMVE1heA0KYGBge3J9DQp0Yl9heDE8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IFRtZWFuX1JvYmluc29uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gYmF0aHkpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IEJPMjJfaWNlY292ZXJsdG1heF9zcyksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50bihsaW1pdHMgPSBjKDAsMC45MyksDQogICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnM9YygnZ3JleScsJ3R1cnF1b2lzZScsJ2JsdWUnKSkrDQogIGdndGl0bGUoIlRlbXAgKG1lYW4gUm9iaW5zb24pIHZzIEJhdGh5IC0gY29sb3VyZWQgYnkgaWNlIGNvdmVyIExUIG1heCIpDQoNCnRiX2F4MQ0KDQpgYGANCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG1iYXRoeV92X3RlbXBfaWNlQ292TFRtYXgucG5nIiksDQogICAgICAgZGV2aWNlID0gInBuZyIsDQogICAgICAgZHBpPTMwMCApDQpgYGANCg0KDQojIyMjIyBCYXRoeSB2IFNhbGluaXR5IGNvbG91cmVkIGJ5IHRlbXANCmBgYHtyfQ0KdGJfYXgxPC0gZ2dwbG90KGRhdGEgPSBlbnZfc3ViX21ldGEsDQogICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBTbWF4X1JvYmluc29uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gYmF0aHkpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IFRtZWFuX1JvYmluc29uKSwNCiAgICAgICAgICAgICBzaXplID0gMSkgKw0KICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGxpbWl0cyA9IGMoLTEuMSwgOC41KSwNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycz1jKCdyZWQnLCd5ZWxsb3cnLCdncmVlbicpKSsNCiAgZ2d0aXRsZSgiU2FsaW5pdHkgKG1heCBSb2JpbnNvbikgdnMgQmF0aHkgLSBjb2xvdXJlZCBieSBhdiBUZW1wIChSKSIpDQoNCnRiX2F4MQ0KDQpgYGANCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG1iYXRoeV92X3NhbE1heF90ZW1wLnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KYGBgDQoNCiMjIyMjIFNhbGluaXR5IHYgVGVtcCBnbm1kczENCmBgYHtyfQ0KdGJfYXgxPC0gZ2dwbG90KGRhdGEgPSBlbnZfc3ViX21ldGEsDQogICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBTbWF4X1JvYmluc29uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gVG1lYW5fUm9iaW5zb24pKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGdubWRzMSksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCnNjYWxlX2NvbG91cl9ncmFkaWVudG4obGltaXRzID0gYyhtaW4oZW52X3N1Yl9tZXRhJGdubWRzMSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgoZW52X3N1Yl9tZXRhJGdubWRzMSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzPWMoJ3JlZCcsJ3llbGxvdycsJ2dyZWVuJykpKw0KICBnZ3RpdGxlKCJUZW1wIChtZWFuIFJvYmluc29uKSB2cyBTYWxpbml0eSAobWF4IFIpIC0gY29sb3VyZWQgYnkgZ25tZHMgcjYgYXggMSAtIGdyZXkgMi41LTUiKQ0KDQp0Yl9heDENCg0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtdGVtcFJtZWFuX3Zfc2FsaW5pdHlSbWF4X25tZHMxLnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KYGBgDQojIyMjIyBTYWxpbml0eSB2IFRlbXAgZGlzc294bWVhbg0KYGBge3J9DQp0Yl9heDE8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IFNtYXhfUm9iaW5zb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBUbWVhbl9Sb2JpbnNvbikpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gQk8yMl9kaXNzb3htZWFuX2JkbWVhbiksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCnNjYWxlX2NvbG91cl9ncmFkaWVudG4obGltaXRzID0gYygyODIuNSwgMzcyLjIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzPWMoJ3JlZCcsJ3llbGxvdycsJ2dyZWVuJykpKw0KICBnZ3RpdGxlKCJUZW1wIChtZWFuIFJvYmluc29uKSB2cyBTYWxpbml0eSAobWF4IFIpIC0gY29sb3VyZWQgYnkgZGlzc29sdmVkIG94eWdlbiIpDQoNCnRiX2F4MQ0KDQpgYGANCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG10ZW1wUm1lYW5fdl9zYWxpbml0eVJtYXhfZGlzb294bWVhbi5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCmBgYA0KIyMjIyMgVFMgLSBpY2Vjb3ZlckxUTWF4DQpgYGB7cn0NCnRiX2F4MTwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gU21heF9Sb2JpbnNvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IFRtZWFuX1JvYmluc29uKSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBCTzIyX2ljZWNvdmVybHRtYXhfc3MpLA0KICAgICAgICAgICAgIHNpemUgPSAxKSArDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudG4obGltaXRzID0gYygwLDAuOTMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzPWMoJ2JsdWUnLCdncmVlbicsJ3JlZCcpKSsNCiAgZ2d0aXRsZSgiVGVtcCAoQXZSKSB2IFNhbGluaXR5IChtYXhSKSAtIGNvbG91cmVkIGJ5IGljZSBjb3ZlciBMVCBtYXgiKQ0KDQp0Yl9heDENCg0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtdGVtcFJtZWFuX3Zfc2FsaW5pdHlSbWF4X2ljZUNvdmVMVG1heC5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9ODAwICkNCmBgYA0KDQoNCiMjIyMjIFggdiBZIC0gZ25tZHMxDQpgYGB7cn0NCnRiX2F4MTwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gWCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IFkpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGdubWRzMSksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50bihsaW1pdHMgPSBjKG1pbihlbnZfc3ViX21ldGEkZ25tZHMxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChlbnZfc3ViX21ldGEkZ25tZHMxKSksDQogICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnM9YygncmVkJywneWVsbG93JywnZ3JlZW4nKSkrDQogIGdndGl0bGUoIkdlb2dyYXBoeSAoWCB2IFkpIC0gY29sb3VyZWQgYnkgZ25tZHMxIikNCg0KZ2dwbG90bHkodGJfYXgxKQ0KDQpgYGANCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG1fWF92X1lfZ25tZHMxLnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KYGBgDQoNCiMjIyMjIFggdiBZIC0gZGVuc2l0eQ0KYGBge3J9DQp0Yl9heDE8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IFgueSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IFkpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHN3RGVuc1JvYl9hdnMpLA0KICAgICAgICAgICAgIHNpemUgPSAxKSArDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudG4obGltaXRzID0gYyhtaW4oZW52X3N1Yl9tZXRhJHN3RGVuc1JvYl9hdnMpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChlbnZfc3ViX21ldGEkc3dEZW5zUm9iX2F2cykpLA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzPWMoJ2JsdWUnLCdncmVlbicsJ3JlZCcpKSsNCiAgZ2d0aXRsZSgiR2VvZ3JhcGh5IChYIHYgWSkgLSBjb2xvdXJlZCBieSB3YXRlciBkZW5zaXR5IikNCg0KdGJfYXgxDQoNCmBgYA0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9YX3ZfWV9zd0RlblJvYmF2cy5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9ODAwICkNCmBgYA0KIyMjIyMgWCB2IFkgLSBkaXNzb3gNCmBgYHtyfQ0KdGJfYXgxPC0gZ2dwbG90KGRhdGEgPSBlbnZfc3ViX21ldGEsDQogICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBYLnksDQogICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBZKSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBCTzIyX2Rpc3NveG1lYW5fYmRtZWFuKSwNCiAgICAgICAgICAgICBzaXplID0gMSkgKw0KICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGxpbWl0cyA9IGMoMjgyLDM3MyksDQogICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnM9YygnYmx1ZScsJ2dyZWVuJywncmVkJykpKw0KICBnZ3RpdGxlKCJHZW9ncmFwaHkgKFggdiBZKSAtIGNvbG91cmVkIGJ5IGRpc3NvdmxlZCBveHlnZW4iKQ0KDQp0Yl9heDENCg0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtX1hfdl9ZX2Rpc3NveC5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9ODAwICkNCmBgYA0KIyMjIyMgWCB2IFkgLSBpY2Vjb3ZlckxUTWF4DQpgYGB7cn0NCnRiX2F4MTwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gWC55LA0KICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gWSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gQk8yMl9pY2Vjb3Zlcmx0bWF4X3NzKSwNCiAgICAgICAgICAgICBzaXplID0gMSkgKw0KICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGxpbWl0cyA9IGMoMC4wMDAwMSwwLjkzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycz1jKCdibHVlJywnZ3JlZW4nLCdyZWQnKSkrDQogIGdndGl0bGUoIkdlb2dyYXBoeSAoWCB2IFkpIC0gY29sb3VyZWQgYnkgaWNlIGNvdmVyIExUIG1heCAtIGdyZXkgPDAuMDAwMDEiKQ0KDQp0Yl9heDENCg0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtX1hfdl9ZX2ljZUNvdmVMVG1heC5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9ODAwICkNCmBgYA0KDQoNCiMjIyMjIFRlbXAgdiBkaXNveGx0bWluIGdubWRzDQpgYGB7cn0NCnRiX2F4MTwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gVG1lYW5fUm9iaW5zb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBCTzIyX2Rpc3NveG1lYW5fYmRtZWFuKSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBnbm1kczEpLA0KICAgICAgICAgICAgIHNpemUgPSAxKSArDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudG4obGltaXRzID0gYygtMi4zLCAyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycz1jKCdyZWQnLCd5ZWxsb3cnLCdncmVlbicpKSsNCiAgZ2d0aXRsZSgiVGVtcCAobWVhbiBSb2JpbnNvbikgdiBkaXNveCBtZWFuIC0gY29sb3VyZWQgYnkgZ25tZHMgYXggMSIpDQoNCnRiX2F4MQ0KDQpgYGANCg0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9UbWVhblJfdl9kaXNzb3hsdG1pbl9nbm1kczEucG5nIiksDQogICAgICAgZGV2aWNlID0gInBuZyIsDQogICAgICAgZHBpPTMwMCApDQoNCmBgYA0KIyMjIyMgVGVtcCB2IGRpc294bHRtaW4gYmF0aHkNCmBgYHtyfQ0KdGJfYXgxPC0gZ2dwbG90KGRhdGEgPSBlbnZfc3ViX21ldGEsDQogICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBUbWVhbl9Sb2JpbnNvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IEJPMjJfZGlzc294bWVhbl9iZG1lYW4pKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGJhdGh5KSwNCiAgICAgICAgICAgICBzaXplID0gMSkgKw0KICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGxpbWl0cyA9IGMoLTcwMiwgLTM4KSwNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycz1jKCdyZWQnLCd5ZWxsb3cnLCdncmVlbicpKSsNCiAgZ2d0aXRsZSgiVGVtcCAobWVhbiBSb2JpbnNvbikgdiBkaXNveCBtZWFuIC0gY29sb3VyZWQgYnkgYmF0aHltZXRyeSIpDQoNCnRiX2F4MQ0KDQpgYGANCg0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbVRtZWFuUl92X2Rpc3NveGx0bWluX2JhdGh5LnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KDQpgYGANCg0KDQoNCiMjIyBQbG90cyB3aXRoIERJU0NSRVRFIGNvbG91ciBzY2FsZXMgKHZhcmlhYmxlcykNCg0KIyMjIyBYIHYgWSB3aXRoIG1sZC1iYXRoeSBjYXRlZ29yaWVzDQpgYGB7cn0NCmRpc19zcGxpdCA8LSBnZ3Bsb3QoZGF0YSA9IGVudiwNCiAgICAgICAgICAgICAgYWVzKHggPSBYLnksDQogICAgICAgICAgICAgICAgICB5ID0gWSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gTUxEbWVhbl9iYXRoeSksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9Y2JQYWxldHRlKSsNCiAjIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQzIikgKw0KICBnZ3RpdGxlKCJFYXN0aW5nIHZzIE5vcnRoaW5nIC0gY29sb3VyZWQgYnkgTWl4ZWQgbGF5ZXIgZGVwdGggcHJveGltaXR5IikNCg0KZGlzX3NwbGl0DQoNCmBgYA0KDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtX1h2WV9NTERtZWFuQmF0aHkucG5nIiksDQogICAgICAgZGV2aWNlID0gInBuZyIsDQogICAgICAgZHBpPTMwMCApDQoNCmBgYA0KDQojIyMgY2F0ZWdvcmlzZSBnbm1kcw0KDQpgYGB7cn0NCmVudl9zdWJfbWV0YSRheDFjYXQ8LWN1dChlbnZfc3ViX21ldGEkZ25tZHMxLCANCiAgICAgIGJyZWFrcz1jKC0zLjIsLTMsLTIsLTEsMCwxLDIsMywzLjQ2KSkNCg0KZW52X3N1Yl9tZXRhJGF4MmNhdDwtY3V0KGVudl9zdWJfbWV0YSRnbm1kczIsIA0KICAgICAgYnJlYWtzPWMoLTEuOSwtMSwwLDEsMiwzLDQsNC45KSkNCmBgYA0KDQoNCiMjIyMgWCB2IFkgd2l0aCBnbm1kcyBheCAxIGFzIEhDIGNhdGVnb3JpZXMNCmBgYHtyfQ0KZGlzX3NwbGl0IDwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICBhZXMoeCA9IFgueSwNCiAgICAgICAgICAgICAgICAgIHkgPSBZKSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBheDFjYXQpLA0KICAgICAgICAgICAgIHNpemUgPSAxKSArDQogIyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jYlBhbGV0dGUpICsjIG5vbi1vcmRlcmVkIGNvbG91cmJsaW5kIHBhbGxldHRlDQogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsgIyBvcmRlcmVkIGNvbG91cmJsaW5kIHBhbGxldHRlDQogIGdndGl0bGUoIkVhc3RpbmcgdnMgTm9ydGhpbmcgLSBjb2xvdXJlZCBieSBnbm1kcyBheGlzIDEgSEMgdW5pdHMiKQ0KDQpkaXNfc3BsaXQNCg0KYGBgDQoNCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG1fWHZZX2F4MWNhdC5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCg0KYGBgDQoNCiMjIyBjYXRlZ29yaXNlIHRlbXAgNS4xDQoNCmBgYHtyfQ0KZW52X3N1Yl9tZXRhJHRlbXA1XzE8LWN1dChlbnZfc3ViX21ldGEkVG1lYW5fUm9iaW5zb24sIA0KICAgICAgYnJlYWtzPWMoLTEuMSwgNS4xLCA4LjUpKQ0KIw0KYGBgDQoNCg0KIyMjIyBYIHYgWSB3aXRoIHRlbXAgNS4xDQpgYGB7cn0NCmRpc19zcGxpdCA8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgYWVzKHggPSBYLnksDQogICAgICAgICAgICAgICAgICB5ID0gWSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gdGVtcDVfMSksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAjIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWNiUGFsZXR0ZSkgKyMgbm9uLW9yZGVyZWQgY29sb3VyYmxpbmQgcGFsbGV0dGUNCiAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArICMgb3JkZXJlZCBjb2xvdXJibGluZCBwYWxsZXR0ZQ0KICBnZ3RpdGxlKCJFYXN0aW5nIHZzIE5vcnRoaW5nIC0gY29sb3VyZWQgYnkgdGVtcCB0aHJlc2hvbGRlZCBhdCA1LjEqQyIpDQoNCmRpc19zcGxpdA0KDQpgYGANCg0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9YdllfdGVtcDVfMS5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCg0KYGBgDQojIyMgY2F0ZWdvcmlzZSBkaXNzb3gNCg0KYGBge3J9DQplbnZfc3ViX21ldGEkZGlzc294YXYzMDU8LWN1dChlbnZfc3ViX21ldGEkQk8yMl9kaXNzb3htZWFuX2JkbWVhbiwgDQogICAgICMgYnJlYWtzPWMoMjU2LCAyODIsIDM2MCkpICNsdG1pbg0KICAgICBicmVha3M9YygyODIuNSwzMDUsMzcyLjIpLA0KICAgICBsYWJlbHM9YygibG93TzIiLCJoaU8yIikpICNtZWFuDQojDQpgYGANCg0KDQojIyMjIFggdiBZIHdpdGggZGlzc294DQpgYGB7cn0NCmRpc19zcGxpdCA8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgYWVzKHggPSBYLnksDQogICAgICAgICAgICAgICAgICB5ID0gWSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZGlzc294YXYzMDUpLA0KICAgICAgICAgICAgIHNpemUgPSAxKSArDQogIyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jYlBhbGV0dGUpICsjIG5vbi1vcmRlcmVkIGNvbG91cmJsaW5kIHBhbGxldHRlDQogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKyAjIG9yZGVyZWQgY29sb3VyYmxpbmQgcGFsbGV0dGUNCiAgZ2d0aXRsZSgiRWFzdGluZyB2cyBOb3J0aGluZyAtIGNvbG91cmVkIGJ5IGRpc3NveCBhdiB0aHJlc2hvbGRlZCBhdCAzMDUiKQ0KDQpkaXNfc3BsaXQNCg0KYGBgDQoNCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG1fWHZZX2Rpc3NveGF2MzA1LnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KDQpgYGANCg0KIyMjIGNhdGVnb3Jpc2UgaWNlQ292TFRNYXgNCg0KYGBge3J9DQplbnZfc3ViX21ldGEkaWNlTXhfZ3QwPC1jdXQoZW52X3N1Yl9tZXRhJEJPMjJfaWNlY292ZXJsdG1heF9zcywgDQogICAgICBicmVha3M9YygwLCAwLjAwMDAxLCAwLjkyODM4KSkNCiMNCmBgYA0KDQoNCiMjIyMgWCB2IFkgd2l0aCB0ZW1wIDUuMQ0KYGBge3J9DQpkaXNfc3BsaXQgPC0gZ2dwbG90KGRhdGEgPSBlbnZfc3ViX21ldGEsDQogICAgICAgICAgICAgIGFlcyh4ID0gWC55LA0KICAgICAgICAgICAgICAgICAgeSA9IFkpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGljZU14X2d0MCksDQogICAgICAgICAgICAgc2l6ZSA9IDEpICsNCiAjIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWNiUGFsZXR0ZSkgKyMgbm9uLW9yZGVyZWQgY29sb3VyYmxpbmQgcGFsbGV0dGUNCiAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArICMgb3JkZXJlZCBjb2xvdXJibGluZCBwYWxsZXR0ZQ0KICBnZ3RpdGxlKCJFYXN0aW5nIHZzIE5vcnRoaW5nIC0gY29sb3VyZWQgYnkgaWNlIExUIE1heCB0aHJlc2hvbGRlZCBhdCA+MCIpDQoNCmRpc19zcGxpdA0KDQpgYGANCg0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9YdllfaWNlTFRteF9ndDAucG5nIiksDQogICAgICAgZGV2aWNlID0gInBuZyIsDQogICAgICAgZHBpPTMwMCApDQoNCmBgYA0KDQoNCg0KDQojIyMjIFggdiBZIHdpdGggZ25tZHMgYXggMiBhcyBIQyBjYXRlZ29yaWVzDQpgYGB7cn0NCmRpc19zcGxpdCA8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgYWVzKHggPSBYLnksDQogICAgICAgICAgICAgICAgICB5ID0gWSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gYXgyY2F0KSwNCiAgICAgICAgICAgICBzaXplID0gMSkgKw0KICMgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9Y2JQYWxldHRlKSArIyBub24tb3JkZXJlZCBjb2xvdXJibGluZCBwYWxsZXR0ZQ0KICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArICMgb3JkZXJlZCBjb2xvdXJibGluZCBwYWxsZXR0ZQ0KICBnZ3RpdGxlKCJFYXN0aW5nIHZzIE5vcnRoaW5nIC0gY29sb3VyZWQgYnkgZ25tZHMgYXhpcyAyIEhDIHVuaXRzIikNCg0KZGlzX3NwbGl0DQoNCmBgYA0KDQoNCg0KDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtX1h2WV9heDJjYXQucG5nIiksDQogICAgICAgZGV2aWNlID0gInBuZyIsDQogICAgICAgZHBpPTMwMCApDQoNCmBgYA0KDQojIyMjIEdubWRzIHcgdGVtcCA1LjENCmBgYHtyfQ0KDQp0X2dtbyA8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gZ25tZHMxLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBnbm1kczIpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGNvb3JkX2ZpeGVkKCkgKw0KICBnZ3RpdGxlKCJHTk1EUyBjb2xvdXJlZCBieSB0ZW1wIDUuMSB0aHJlc2hvbGQiLA0KICAgICAgICAgIHN1YnRpdGxlID0gIkZpcnN0IHJ1biIpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZmFjdG9yKHRlbXA1XzUpKSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gMiwNCiAgICAgICAgICAgICBjb2xvdXIgPSAibGlnaHRncmF5IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gMiwNCiAgICAgICAgICAgICBjb2xvdXIgPSAibGlnaHRncmF5IikrDQogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKG5jb2w9MikpDQoNCnRfZ21vDQpgYGANCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KZ2dzYXZlKGZpbGVuYW1lID0gZmlsZS5wYXRoKGRhdGFQYXRoLCJvdXRwdXRzL0hpRGVuc0JlbG93MTUwMG1fZ25tZHNfdGVtcDVfMS5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCmBgYA0KIyMjIyBHbm1kcyB3IGRpc3NveCAzMDUNCmBgYHtyfQ0KDQpvX2dtbyA8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gZ25tZHMxLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBnbm1kczIpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGNvb3JkX2ZpeGVkKCkgKw0KICBnZ3RpdGxlKCJHTk1EUyBjb2xvdXJlZCBieSBkaXNzb3ggMzA1IHRocmVzaG9sZCIsDQogICAgICAgICAgc3VidGl0bGUgPSAiRmlyc3QgcnVuIikgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmYWN0b3IoZGlzc294MzA1KSkpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsDQogICAgICAgICAgICAgY29sb3VyID0gImxpZ2h0Z3JheSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsDQogICAgICAgICAgICAgY29sb3VyID0gImxpZ2h0Z3JheSIpKw0KICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZChuY29sPTIpKQ0KDQpvX2dtbw0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtX2dubWRzX2Rpc3NveDMwNS5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCmBgYA0KDQojIyMjIEdubWRzIHcgaWNlTFQgbWF4ID4wDQpgYGB7cn0NCg0KaV9nbW8gPC0gZ2dwbG90KGRhdGEgPSBlbnZfc3ViX21ldGEsDQogICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IGdubWRzMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZ25tZHMyKSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBjb29yZF9maXhlZCgpICsNCiAgZ2d0aXRsZSgiR05NRFMgY29sb3VyZWQgYnkgaWNlIG1heCA+MCB0aHJlc2hvbGQiLA0KICAgICAgICAgIHN1YnRpdGxlID0gIkZpcnN0IHJ1biIpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZmFjdG9yKGljZU14X2d0MCkpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAyLA0KICAgICAgICAgICAgIGNvbG91ciA9ICJsaWdodGdyYXkiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAyLA0KICAgICAgICAgICAgIGNvbG91ciA9ICJsaWdodGdyYXkiKSsNCiAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQobmNvbD0yKSkNCg0KaV9nbW8NCmBgYA0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9nbm1kc19pY2VNeGd0MC5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCmBgYA0KDQpgYGB7cn0NCmNvbXA8LWlfZ21vK29fZ21vK3RfZ21vDQpgYGANCiMjIyMjIFNhdmUgdGhlIHBsb3QNCmBgYHtyfQ0KDQoNCiMjIyMjIFNhdmUgc29tZSBvdXRwdXRzDQoNCmdnZXhwb3J0KGNvbXAsDQogICAgICAgICAgZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9nbm1kc19jb21wYXJlLnBuZyIpLA0KICAgICAgICAgIHdpZHRoID0gMTUwMCwNCiAgICAgICAgICBoZWlnaHQgPSA1MDApDQoNCmBgYA0KDQoNCg0KDQojIyMjIFggdiBZIHdpdGggbGFuZHNjYXBlDQpgYGB7cn0NCmRpc19zcGxpdCA8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgYWVzKHggPSBYLnksDQogICAgICAgICAgICAgICAgICB5ID0gWSkpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gYXMuZmFjdG9yKGxhbmRzY2FwZSkpLA0KICAgICAgICAgICAgIHNpemUgPSAxKSArDQogIyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jYlBhbGV0dGUpICsjIG5vbi1vcmRlcmVkIGNvbG91cmJsaW5kIHBhbGxldHRlDQogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKyAjIG9yZGVyZWQgY29sb3VyYmxpbmQgcGFsbGV0dGUNCiAgZ2d0aXRsZSgiRWFzdGluZyB2cyBOb3J0aGluZyAtIGNvbG91cmVkIGJ5IGxhbmRzY2FwZSIpDQoNCmRpc19zcGxpdA0KDQpgYGANCg0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9YdllfbGFuZHNjYXBlLnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KDQpgYGANCg0KDQojIEdOTURTIFBMT1RTDQoNCiMjIyMjIyBjb2xvdXIgcGFsZXR0ZSB0byBjb3BlIHdpdGggdXAgdG8gMjUgY2F0ZWdvcmljYWwgY29sb3Vycw0KYGBge3J9DQpjMjUgPC0gYygNCiAgImRvZGdlcmJsdWUyIiwgIiNFMzFBMUMiLCAjIHJlZA0KICAiZ3JlZW40IiwNCiAgIiM2QTNEOUEiLCAjIHB1cnBsZQ0KICAiI0ZGN0YwMCIsICMgb3JhbmdlDQogICJibGFjayIsICJnb2xkMSIsDQogICJza3libHVlMiIsICIjRkI5QTk5IiwgIyBsdCBwaW5rDQogICJwYWxlZ3JlZW4yIiwNCiAgIiNDQUIyRDYiLCAjIGx0IHB1cnBsZQ0KICAiI0ZEQkY2RiIsICMgbHQgb3JhbmdlDQogICJncmF5NzAiLCAia2hha2kyIiwNCiAgIm1hcm9vbiIsICJvcmNoaWQxIiwgImhpRGVuc19iMTUwMHBpbmsxIiwgImJsdWUxIiwgInN0ZWVsYmx1ZTQiLA0KICAiZGFya3R1cnF1b2lzZSIsICJncmVlbjEiLCAieWVsbG93NCIsICJ5ZWxsb3czIiwNCiAgImRhcmtvcmFuZ2U0IiwgImJyb3duIg0KKQ0KYGBgDQoNCg0KDQojIyMjIGdubWRzIHdpdGggZGVuc2l0eSBjYXRlZ29yaWVzDQoNCmBgYHtyfQ0Kc3VtbWFyeShlbnZfc3ViX21ldGEkc3dEZW5zUm9iX2F2cykNCg0KZW52X3N1Yl9tZXRhJGRlbnNDYXQ8LWN1dChlbnZfc3ViX21ldGEkc3dEZW5zUm9iX2F2cywgDQogICAgICBicmVha3M9YygxMDM1LDEwMzYsMTAzNywxMDM4LDEwMzksMTA0MCwxMDQxKSkNCmBgYA0KDQoNCmBgYHtyfQ0KDQpwX2RlbnMgPC0gZ2dwbG90KGRhdGEgPSBlbnZfc3ViX21ldGEsDQogICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IGdubWRzMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZ25tZHMyKSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBjb29yZF9maXhlZCgpICsNCiAgZ2d0aXRsZSgiR05NRFMgY29sb3VyZWQgYnkgZGVuc2l0eSBiaW5zIikgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmYWN0b3IoZGVuc0NhdCkpKSArDQogICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jMjUpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gMiwNCiAgICAgICAgICAgICBjb2xvdXIgPSAibGlnaHRncmF5IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gMiwNCiAgICAgICAgICAgICBjb2xvdXIgPSAibGlnaHRncmF5IikrDQogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKG5jb2w9MikpDQoNCmdncGxvdGx5KHBfZGVucykNCg0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtX2dubWRzX2RlbnNpdHlDYXQucG5nIiksDQogICAgICAgZGV2aWNlID0gInBuZyIsDQogICAgICAgZHBpPTMwMCApDQoNCmBgYA0KDQoNCiMjIyMgZ25tZHMgd2l0aCBkZW5zaXR5IDEwMzYgdGhyZXNob2xkDQoNCmBgYHtyfQ0Kc3VtbWFyeShlbnZfc3ViX21ldGEkc3dEZW5zUm9iX2F2cykNCg0KZW52X3N1Yl9tZXRhJGRlbnNDYXQxMDM2PC1jdXQoZW52X3N1Yl9tZXRhJHN3RGVuc1JvYl9hdnMsIA0KICAgICAgYnJlYWtzPWMoMTAzNSwxMDM2LDEwNDEpKQ0KYGBgDQoNCg0KYGBge3J9DQoNCnBfZGVucyA8LSBnZ3Bsb3QoZGF0YSA9IGVudl9zdWJfbWV0YSwNCiAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gZ25tZHMxLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBnbm1kczIpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGNvb3JkX2ZpeGVkKCkgKw0KICBnZ3RpdGxlKCJHTk1EUyBjb2xvdXJlZCBieSBkZW5zaXR5IHRocmVzaG9sZCAxMDM2IikgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmYWN0b3IoZGVuc0NhdDEwMzYpKSkgKw0KICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YzI1KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsDQogICAgICAgICAgICAgY29sb3VyID0gImxpZ2h0Z3JheSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsDQogICAgICAgICAgICAgY29sb3VyID0gImxpZ2h0Z3JheSIpKw0KICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZChuY29sPTIpKQ0KDQpnZ3Bsb3RseShwX2RlbnMpDQoNCmBgYA0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9nbm1kc19kZW5zaXR5Q2F0MTAzNi5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCg0KYGBgDQoNCg0KDQoNCg0KIyMjIyBnbm1kcyB3aXRoIGJhdGh5IGNhdGVnb3JpZXMNCg0KYGBge3J9DQpzdW1tYXJ5KGVudl9zdWJfbWV0YSRiYXRoeSkNCg0KZW52X3N1Yl9tZXRhJGJhdGh5Q2F0PC1jdXQoZW52X3N1Yl9tZXRhJGJhdGh5LCANCiAgICAgIGJyZWFrcz1jKC0yNzE3LC0yNjAwLC0yNTAwLC0yNDAwLC0yMzAwLC0yMjAwLC0yMTAwLC0yMDAwLC0xOTAwLC0xODAwLC0xNzAwLC0xNjAwLC0xNTA0KSwNCiAgICAgIGxhYmVscz1jKCI+IDI2MDBtIiwiMjUwMC0yNjAwbSIsIjI0MDAtMjUwMG0iLCIyMzAwLTI0MDBtIiwiMjIwMC0yMzAwbSIsIjIxMDAtMjIwMG0iLA0KICAgICAgICAgICAgICAgIjIwMDAtMjEwMG0iLCIxOTAwLTIwMDBtIiwiMTgwMC0xOTAwbSIsIjE3MDAtMTgwMG0iLA0KICAgICAgICAgICAgICAgIjE2MDAtMTcwMG0iLCI8IDE2MDBtIikpDQpgYGANCg0KDQpgYGB7cn0NCg0KcF9iYXRoIDwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBnbm1kczEsDQogICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGdubWRzMikpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgY29vcmRfZml4ZWQoKSArDQogIGdndGl0bGUoIkdOTURTIGNvbG91cmVkIGJ5IHNlZGltZW50IGNsYXNzIikgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBiYXRoeUNhdCkpICsNCiAgc2NhbGVfZmlsbF9iaW5uZWQoKSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsDQogICAgICAgICAgICAgY29sb3VyID0gImxpZ2h0Z3JheSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsDQogICAgICAgICAgICAgY29sb3VyID0gImxpZ2h0Z3JheSIpKw0KICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZChuY29sPTIpKQ0KDQpnZ3Bsb3RseShwX2JhdGgpDQoNCg0KYGBgDQojIyMjIyBTYXZlIHRoZSBwbG90DQpgYGB7cn0NCmdnc2F2ZShmaWxlbmFtZSA9IGZpbGUucGF0aChkYXRhUGF0aCwib3V0cHV0cy9IaURlbnNCZWxvdzE1MDBtX2dubWRzX2JhaHR5Q2F0LnBuZyIpLA0KICAgICAgIGRldmljZSA9ICJwbmciLA0KICAgICAgIGRwaT0zMDAgKQ0KDQpgYGANCg0KIyBnbm1kcyB3aXRoIHRheGENCg0KDQpgYGB7cn0NCg0KcF9iYXRoIDwtIGdncGxvdChkYXRhID0gZW52X3N1Yl9tZXRhLA0KICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBnbm1kczEsDQogICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGdubWRzMikpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgY29vcmRfZml4ZWQoKSArDQogIGdndGl0bGUoIkdOTURTIGNvbG91cmVkIGJ5IHNlZGltZW50IGNsYXNzIikgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhcy5mYWN0b3IoVW1iZWxsdWxhX2VuY3JpbnVzKSkpICsNCiAgc2NhbGVfZmlsbF9iaW5uZWQodHlwZSA9ICJ2aXJpZGlzIikrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAyLA0KICAgICAgICAgICAgIGNvbG91ciA9ICJsaWdodGdyYXkiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAyLA0KICAgICAgICAgICAgIGNvbG91ciA9ICJsaWdodGdyYXkiKSsNCiAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQobmNvbD0yKSkNCg0KZ2dwbG90bHkocF9iYXRoKQ0KDQoNCmBgYA0KIyMjIyMgU2F2ZSB0aGUgcGxvdA0KYGBge3J9DQpnZ3NhdmUoZmlsZW5hbWUgPSBmaWxlLnBhdGgoZGF0YVBhdGgsIm91dHB1dHMvSGlEZW5zQmVsb3cxNTAwbV9nbm1kc19iYWh0eUNhdC5wbmciKSwNCiAgICAgICBkZXZpY2UgPSAicG5nIiwNCiAgICAgICBkcGk9MzAwICkNCg0KYGBgDQoNCg0KDQoNCg0KIyBTYXZlIGVudmlyb25tZW50DQoNCkVESVQgQVJFQSBGSVJTVCENCg0KYGBge3J9DQpzYXZlLmltYWdlKCJJOi9TY3JpcHRzL2RlZXBzZWFOaU4vUmVudl9kZWVwc2VhTmlOX0hpRGVuc0JlbG93MTUwMG0uUkRhdGEiKSAjIGVkaXQgYXJlYSBmaXJzdA0KDQpgYGANCg0KTk9XIENMRUFSIEVOVklST05NRU5UIEJFRk9SRSBSVU5OSU5HIEZPUiBORVcgQVJFQQ0KDQo=